/********************************************
 * 功能说明: 
 * 模块名称: 
 * 系统名称: 
 * 软件版权: 
 * 系统版本: 1.0.0
 * 开发人员: zhangfb
 * 开发时间: 2019/4/1 0:28
 * 审核人员: 
 * 相关文档: 
 * 修改记录: 修改日期 修改人员 修改说明
 *********************************************/
package com.hyacinth.support;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;

/**
 * 数据库操作代理类
 * @author zhangfb
 * @version 1.0.0.1
 * @since JDK 1.8
 */
public class DBOptionProxy implements InvocationHandler {

    private static final Logger LOGGER = LoggerFactory.getLogger(DBOptionProxy.class);

    private DBOptionProcessor processor;

    public DBOptionProxy(DBOptionProcessor processor) {
        this.processor = processor;
    }

    /**
     * 获取被代理接口实例对象
     */
    public DBOption getProxy() {
        return (DBOption) Proxy.newProxyInstance(processor.getClass().getClassLoader(), processor.getClass().getInterfaces(), this);
    }

    /**
     * 对数据库链接统一处理
     * @param proxy   代理对象---this
     * @param method  代理方法
     * @param args    参数
     * @return        代理结果
     * @throws Throwable  异常
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 获取方法名
        String methodName = method.getName();
        // Object内置的方法处理
        if (Object.class == method.getDeclaringClass()) {
            if ("equals".equals(methodName)) {
                return proxy == args[0];
            } else if ("hashCode".equals(methodName)) {
                return System.identityHashCode(proxy);
            } else if ("toString".equals(methodName)) {
                return proxy.getClass().getName() + "@" +
                        Integer.toHexString(System.identityHashCode(proxy)) +
                        ", with InvocationHandler " + this;
            } else {
                throw new IllegalStateException(String.valueOf(method));
            }
        }

        // 内部方法
        if ("getConnect".equals(methodName)) {
            return processor.getConnect();
        }
        if ("getDataSource".equals(methodName)) {
            return processor.getHyds();
        }

//        // 第1个参数是Connection,可以为空
//        if (null != args[0] && args[0] instanceof Connection) {
//
//        }
        Connection connect = (Connection) args[0];
        if (connect == null) {
            // 为空则新创建连接
            connect = processor.getConnect();
        }

        Object result = null;
        try {
            args[0] = connect;
            result = method.invoke(processor, args);
        } catch (Exception e) {
            LOGGER.error("执行{}方法出错", method, e);
        } finally {
            // 关闭数据源
            processor.close(connect);
            LOGGER.error("关闭数据源!!!");
        }
        return result;
    }
}
